using System;
using System.Diagnostics;

namespace Schedulr.Helpers
{
    /// <summary>
    /// An object that handles all tracing for a certain trace source.
    /// </summary>
    internal sealed class Tracer : IDisposable
    {
        #region Fields

        /// <summary>
        /// The trace source to trace to.
        /// </summary>
        private TraceSource trace;

        #endregion

        #region Constructor

        /// <summary>
        /// Creates a new <see cref="Tracer"/> instance.
        /// </summary>
        /// <param name="traceSourceName">The name of the trace source to write to.</param>
        public Tracer(string traceSourceName)
        {
            this.trace = new TraceSource(traceSourceName, SourceLevels.Warning);
        }

        #endregion

        #region Trace

        /// <summary>
        /// Traces a message.
        /// </summary>
        /// <param name="message">The message to trace.</param>
        /// <param name="eventType">The type of event that caused the trace.</param>
        public void Trace(string message, TraceEventType eventType)
        {
            this.trace.TraceEvent(eventType, 0, message);
            this.trace.Flush();
        }

        #endregion

        #region Dispose & Finalize

        /// <summary>
        /// Disposes the current object.
        /// </summary>
        /// <param name="disposing"><see langword="true"/> if the object is being disposed explicitly, <see langword="false"/> if it is being disposed by the managed runtime.</param>
        private void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (this.trace != null)
                {
                    this.trace.Flush();
                    this.trace.Close();
                }
            }
        }

        /// <summary>
        /// Disposes the current object.
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// Finalizes the current object.
        /// </summary>
        ~Tracer()
        {
            Dispose(false);
        }

        #endregion
    }
}